/*
 * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
 *
 * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
 *                           Jerremy Koot (jkoot@snes9x.com)
 *
 * Super FX C emulator code
 * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
 *                           Gary Henderson.
 * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
 *
 * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
 * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_.
 * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com).
 *
 * DOS port code contains the works of other authors. See headers in
 * individual files.
 *
 * Snes9x homepage: http://www.snes9x.com
 *
 * Permission to use, copy, modify and distribute Snes9x in both binary and
 * source form, for non-commercial purposes, is hereby granted without fee,
 * providing that this license information and copyright notice appear with
 * all copies and any derived work.
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event shall the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Snes9x is freeware for PERSONAL USE only. Commercial users should
 * seek permission of the copyright holders first. Commercial use includes
 * charging money for Snes9x or software derived from Snes9x.
 *
 * The copyright holders request that bug fixes and improvements to the code
 * should be forwarded to them so everyone can benefit from the modifications
 * in future versions.
 *
 * Super NES and Super Nintendo Entertainment System are trademarks of
 * Nintendo Co., Limited and its subsidiary companies.
 */
#ifdef DREAMCAST
#include <kos.h>
#endif

#include <QImage>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifndef WIN32
#include <unistd.h>
#else
#include <direct.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <signal.h>

#include "snes9x.h"
#include "memmap.h"
#include "debug.h"
#include "ppu.h"
#include "snapshot.h"
#include "gfx.h"
#include "display.h"
#include "apu.h"
#include "keydef.h"

#include "machine.h"

#define COUNT(a) (sizeof(a) / sizeof(a[0]))

QImage *snesFrameBuffer;
QByteArray *snesAudioBuffer;
uint16 *RGBconvert;
extern quint32 cl, cs;
extern int MouseXpos, MouseYpos, MouseLbutton, MouseRbutton, SuperscopeTurbo, SuperscopeCursor;
extern quint32 MouseButton;
extern int emu_hires;

#ifndef _ZAURUS
int S9xMinCommandLineArgs ()
{
    return (2);
}

void S9xGraphicsMode ()
{
}

void S9xTextMode ()
{
}
#endif

void S9xInitDisplay (int /*argc*/, char ** /*argv*/)
{
    snesFrameBuffer = new QImage(EMU_SCREEN_WIDTH_BUFFER, EMU_SCREEN_HEIGHT_BUFFER, QImage::Format_RGB16);
    snesAudioBuffer = new QByteArray(512*16,0);
    if (snesFrameBuffer == NULL || snesAudioBuffer == NULL)
    {
        printf("Couldn't init Buffers");
        S9xExit();
    }
    GFX.Screen = snesFrameBuffer->bits(); //(uint8 *)malloc( EMU_SCREEN_WIDTH * EMU_SCREEN_HEIGHT * EMU_SCREEN_DEPTH_BYTES);
    GFX.Pitch = EMU_SCREEN_PITCH;
    GFX.SubScreen = (uint8 *)malloc(EMU_SCREEN_WIDTH_BUFFER * EMU_SCREEN_HEIGHT_BUFFER* EMU_SCREEN_DEPTH_BYTES);
    GFX.ZBuffer = (uint8 *)malloc(EMU_SCREEN_WIDTH_BUFFER * EMU_SCREEN_HEIGHT_BUFFER * EMU_SCREEN_DEPTH_BYTES);
    GFX.SubZBuffer = (uint8 *)malloc(EMU_SCREEN_WIDTH_BUFFER * EMU_SCREEN_HEIGHT_BUFFER * EMU_SCREEN_DEPTH_BYTES);

}

void S9xDeinitDisplay ()
{
    free(GFX.SubScreen);
    free(GFX.ZBuffer);
	free(GFX.SubZBuffer);
    delete snesFrameBuffer;
    delete snesAudioBuffer;
}

uint8 palete[256][3];
uint16 palete565[256];

void S9xSetPalette ()
{
    if(Settings.SixteenBit == true) return;
    uint16 Brightness = (IPPU.MaxBrightness) * 140;
    uint8 r, g, b;
    for(int i=0;i<256;i++){
        r = ((PPU.CGDATA[i] >> 0) & 0x1F) * Brightness >> 8;
        g = ((PPU.CGDATA[i] >> 5) & 0x1F) * Brightness >> 8;
        b = ((PPU.CGDATA[i] >> 10) & 0x1F) * Brightness >> 8;
        palete[i][0]=r;
        palete[i][1]=g;
        palete[i][2]=b;
        palete565[i]=((r / 8) << 11) | ((g / 4) << 5) | (b / 8);
    }
}


void S9xSetTitle (const char *  title)
{
}

#ifndef _ZAURUS
const char *S9xSelectFilename (const char *def, const char *dir1,
			    const char *ext1, const char *title)
{
    static char path [PATH_MAX];
    char buffer [PATH_MAX];

    S9xTextMode ();
    printf ("\n%s (default: %s): ", title, def);
    fflush (stdout);
    if (fgets (buffer, sizeof (buffer) - 1, stdin))
    {
	char *p = buffer;
	while (isspace (*p) || *p == '\n')
	    p++;
	if (!*p)
	{
	    strcpy (buffer, def);
	    p = buffer;
	}

	char *q = strrchr (p, '\n');
	if (q)
	    *q = 0;

	char fname [PATH_MAX];
	char drive [_MAX_DRIVE];
	char dir [_MAX_DIR];
	char ext [_MAX_EXT];

	_splitpath (p, drive, dir, fname, ext);
	_makepath (path, drive, *dir ? dir : dir1, fname, *ext ? ext : ext1);
	S9xGraphicsMode ();
	return (path);
    }
    S9xGraphicsMode ();
    return (NULL);
}

void S9xParseDisplayArg (char **argv, int &ind, int)
{
}

void S9xExtraUsage ()
{
}

bool8 S9xReadMousePosition (int  which1 , int &x , int &y ,
			    uint32 &buttons )
{
    if (which1 == 0)
    {
    if(emu_hires == 2){
    x = MouseXpos*(256.0 / (double)EMU_SCREEN_WIDTH);
    y = MouseYpos*(224.0 / (double)EMU_SCREEN_HEIGHT);
    }else{
    x = MouseXpos-EMU_SCREEN_PAD;
    y = MouseYpos;
    }
	buttons = MouseButton;
	return (TRUE);
    }
    return (FALSE);
}

bool8 S9xReadSuperScopePosition (int &x , int &y ,
				 uint32 &buttons )
{
    if(emu_hires == 2){
    x = MouseXpos*(256.0 / (double)EMU_SCREEN_WIDTH);
    y = MouseYpos*(224.0 / (double)EMU_SCREEN_HEIGHT);
    }else{
    x = MouseXpos-EMU_SCREEN_PAD;
    y = MouseYpos;
    }
    buttons = (MouseLbutton & 3)|(SuperscopeCursor << 1)|(SuperscopeTurbo << 2)|(MouseRbutton << 3);
    return (TRUE);
}
#endif

void S9xMessage (int /* type */, int /* number */, const char *message)
{
    fprintf (stderr, "%s\n", message);
}


bool JustifierOffscreen()
{
	return false;
}

void JustifierButtons(uint32& justifiers)
{
}

START_EXTERN_C
uint8 snes9x_clear_change_log = 0;
END_EXTERN_C

const char *S9xGetFilenameInc (const char *e)
{
    static char filename [_MAX_PATH + 1];
    char drive [_MAX_DRIVE + 1];
    char dir [_MAX_DIR + 1];
    char fname [_MAX_FNAME + 1];
    char ext [_MAX_EXT + 1];
    char *ptr;
    struct stat buf;

    if (strlen (S9xGetSnapshotDirectory()))
    {
        _splitpath (Memory.ROMFilename, drive, dir, fname, ext);
        strcpy (filename, S9xGetSnapshotDirectory());
        strcat (filename, "/");
        strcat (filename, fname);
        ptr = filename + strlen (filename);
        strcat (filename, "00/");
        strcat (filename, e);
    }
    else
    {
        _splitpath (Memory.ROMFilename, drive, dir, fname, ext);
        strcat (fname, "00/");
        _makepath (filename, drive, dir, fname, e);
        ptr = strstr (filename, "00/");
    }

    do
    {
        if (++*(ptr + 2) > '9')
        {
            *(ptr + 2) = '0';
            if (++*(ptr + 1) > '9')
            {
                *(ptr + 1) = '0';
                if (++*ptr > '9')
                    break;
            }
        }
    } while( stat(filename, &buf) == 0 );

    return (filename);
}

START_EXTERN_C
char* osd_GetPackDir()
{
  static char filename[_MAX_PATH];
  memset(filename, 0, _MAX_PATH);

  if(strlen(S9xGetSnapshotDirectory())!=0)
    strcpy (filename, S9xGetSnapshotDirectory());
  else
  {
    char dir [_MAX_DIR + 1];
    char drive [_MAX_DRIVE + 1];
    char name [_MAX_FNAME + 1];
    char ext [_MAX_EXT + 1];
    _splitpath(Memory.ROMFilename, drive, dir, name, ext);
    _makepath(filename, drive, dir, NULL, NULL);
  }

  if(!strncmp((char*)&Memory.ROM [0xffc0], "SUPER POWER LEAG 4   ", 21))
  {
    if (getenv("SPL4PACK"))
      return getenv("SPL4PACK");
    else
      strcat(filename, "/SPL4-SP7");
  }
  else if(!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY      ",21))
  {
    if (getenv("MDHPACK"))
      return getenv("MDHPACK");
    else
      strcat(filename, "/SMHT-SP7");
  }
  else if(!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21))
  {
    if (getenv("FEOEZPACK"))
      return getenv("FEOEZPACK");
    else
      strcat(filename, "/FEOEZSP7");
  }
  else if(!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO",21))
  {
    if (getenv("SJNSPACK"))
      return getenv("SJNSPACK");
    else
      strcat(filename, "/SJUMPSP7");
  } else strcat(filename, "/MISC-SP7");
  return filename;
}
END_EXTERN_C
